/******************************************************************************
Filename    : rmp_platform_ch32v307vc.h
Author      : pry
Date        : 24/06/2017
Licence     : The Unlicense; see LICENSE for details.
Description : The configuration file for CH32V307VC RISC-V chip.
              The chip features a WCH homebrew QingKe core which WCH claims to
              be RISC-V, yet it has multiple pecularities that must be carefully
              considered when the port is used:
              -----------------------------------------------------------------
              1. Esoteric memory configuration
              This chip is esoteric in the sense that it integrates an SPI
              flash chiplet with the main chip that only have 320k SRAM, which
              is different from most such chips where manufacturers allow using
              an arbitrary size external SPI flash. To imitate a product with
              real embedded flash, WCH choose not to add ICache or prefetcher
              (which is the common case for these chips) but to copy a portion
              of the flash onto the 320k SRAM and use it as code memory. Hence
              the SRAM must be split into "FLASH" and user-usable "SRAM", and
              the possible configurations include:
              192k Flash + 128k RAM
              224k Flash + 96k RAM
              256k Flash + 64k RAM
              288k Flash + 32k RAM
              Care must be taken to select the correct configuration.
              -----------------------------------------------------------------
              2. Nonstandard interrupt entry behavior
              This chip is also nonstandard in terms of interrupt entry
              behavior. Upon interrupt entry, it will NOT disable interrupts,
              and leave the MIE bit set. According to WCH, this facilitates the
              so-called "M-mode interrupt preemption". However, such preemption
              will NOT work at all unless the processor guarantees to execute at
              least one instruction between interrupts. To see why, consider a
              situation where a low-priority interrupt is immediately followed
              by a high-priority one. The low-priority interrupt will never get
              a chance to save its mepc even if its first instructions are to do
              so or disable interrupts, because the high-priority interrupt WILL
              preempt it before it can even execute one instruction.
              The remedy here is to (1) disable interrupt preemption altogether,
              or (2) believe that somehow WCH allows low-level interrupt to at
              least execute one instruction before it gets preempted, so we can
              disable interrupts when we enter interrupts, save mepc, and reenable
              interrupts. The (2) will require some modifications to the standard
              context switch code, and we refrain from doing so.
              Such interrupt entry behavior also influences the context saving
              and restoring of RMP. The RMP's context switch on RISC-V requires
              that (1) the context generated by interrupt handlers can be
              restored by RMP_YIELD, and (2) the context generated by RMP_YIELD
              can be restored by interrupts. However, when using the generic port
              interrupt context save/restore assembly macros without adaptation,
              the mstatus pushed by the interrupt handlers will have the MIE bit
              set. This will lead to premature interrupt enabling in RMP_YIELD,
              which enables potential interrupts to preempt it before it finishes
              the context switch. This breaks the kernel critical section invariant
              and can lead to cryptic crashes that are very hard to track down.
              The remedy here is to (1) configure the interrupts so no interrupt
              nesting can happen, and (2) manually disable interrupt upon interrupt
              handler entry by adding "CSRCI mstatus,8" before the generic macros.
******************************************************************************/

/* Define ********************************************************************/
/* The HAL library */
#include "ch32v30x.h"
#include "debug.h"
#include "core_riscv.h"

/* Debugging */
/* Assertion */
#define RMP_ASSERT_ENABLE           (1U)
/* Invalid parameter checking */
#define RMP_CHECK_ENABLE            (1U)
/* Debug logging */
#define RMP_DBGLOG_ENABLE           (1U)

/* System */
/* The maximum number of preemption priorities */
#define RMP_PREEMPT_PRIO_NUM        (32U)
/* The maximum number of slices allowed */
#define RMP_SLICE_MAX               (100000U)
/* The maximum number of semaphore counts allowed */
#define RMP_SEM_CNT_MAX             (1000U)
/* The stack size of the init thread */
#define RMP_INIT_STACK_SIZE         (256U)

/* GUI */
#define RMP_GUI_ENABLE              (0U)
/* Anti-aliasing */
#define RMP_GUI_ANTIALIAS_ENABLE    (0U)
/* Widgets */
#define RMP_GUI_WIDGET_ENABLE       (0U)

/* 1ms tick time for 144MHz */
#define RMP_RV32P_OSTIM_VAL         (144000U)
/* What is the FPU type? */
#define RMP_RV32P_COP_RVF           (1U)
#define RMP_RV32P_COP_RVD           (0U)

/* Reprogram the timer or clear timer interrupt flags */
#define RMP_RV32P_TIM_CLR()         (SysTick->SR=0U)

/* Other low-level initialization stuff - clock and serial. 
 * This is the default initialization sequence. If you wish to supply
 * your own, just redirect this macro to a custom function, or do your
 * initialization stuff in the initialization hook (RMP_START_HOOK). */
#define RMP_RV32P_LOWLVL_INIT() \
do \
{ \
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); \
    USART_Printf_Init(115200U); \
    RMP_Int_Disable(); \
    SysTick->CMP=RMP_RV32P_OSTIM_VAL; \
    SysTick->CTLR=0x3FU; \
    NVIC_EnableIRQ(SysTicK_IRQn); \
} \
while(0)

/* This is for debugging output */
#define RMP_RV32P_PUTCHAR(CHAR)     putchar(CHAR)
/* End Define ****************************************************************/

/* End Of File ***************************************************************/

/* Copyright (C) Evo-Devo Instrum. All rights reserved ***********************/
